#pragma once

#include "AbstractHeapNode.h"

namespace WTB{

	class CAbstractHeap
	{
	public:
		CAbstractHeap(void);
		virtual ~CAbstractHeap(void);
		/*
		* not in support of multi-thread
		*/
		int InsertHeapNode(CAbstractHeapNode* _pNode);
		/*
		* not in support of multi-thread
		*/
		void DropHeapNode(CAbstractHeapNode* _pNode);
		/*
		* not in support of multi-thread
		*/
		CAbstractHeapNode* TopHeapNode(){
			if (m_uCurrentHeapSize > 0)
			{
				return m_arrNodePoint[HEAP_ROOT_INDEX];
			}
			return NULL;
		}
		/*
		* not in support of multi-thread
		*/
		CAbstractHeapNode* PopHeapNode();

	protected:
		virtual void ShiftUpHeap(unsigned _uHoleIndex, CAbstractHeapNode* _pNode) = 0;
		virtual void ShiftDownHeap(unsigned _uHoleIndex, CAbstractHeapNode* _pNode) = 0;
	private:
		int ReserveHeap(unsigned _uSize);
		void DropHeapNode(unsigned _index){
			CAbstractHeapNode* pNode = NULL;
			pNode = m_arrNodePoint[_index];
			pNode->SetHeapIndex(CAbstractHeapNode::MAX_INDEX_PLUS_1);
			CAbstractHeapNode* pLastNode = m_arrNodePoint[--m_uCurrentHeapSize];
			m_arrNodePoint[m_uCurrentHeapSize] = NULL;
			if (m_uCurrentHeapSize > 0)
			{
				unsigned uHoleIndex = _index;
				ShiftDownHeap(uHoleIndex,pLastNode);
			}
		}
	protected:
		CAbstractHeapNode** m_arrNodePoint;
		unsigned m_uCurrentHeapSize;
		unsigned m_uMaxHeapSize;
	public:
		static const unsigned MAX_HEAP_SIZE = -1;
		static const unsigned HEAP_ROOT_INDEX = 0;

	};

}